#include "./tx_memory.h"
#include "../mem_inner.h"

/* 内存管理-threadx系统的内存管理算法 */


/* 内存管理-Threadx */

#if defined (CONFIG_MEM_TYPE_THREADX)

/* static var */


/* static sal func */

static void *_init(void *obj, void *addr_start, void *addr_end)
{
    size_t size;

    if (addr_start >= addr_end)
    {
        return NULL;
    }
    else
    {
        size = (uint32_t)addr_end - (uint32_t)addr_start;
        _tx_byte_pool_create(obj, addr_start, size);
    }

    // printf("mem_tx_sal init (0x%08X - 0x%08X)\r\n", (uint32_t)addr_start, (uint32_t)addr_end);

    return obj;
}

static void _free(void *obj, void *ptr)
{
    _tx_byte_release(obj, ptr);
}

static void *_malloc(void *obj, size_t bytes)
{
    void *ptr = NULL;

    _tx_byte_allocate(obj, (void**)&ptr, bytes);

    return ptr;
}

static void *_realloc(void *obj, void *ptr, size_t bytes)
{
    void *pp;
    
    /* Allocate area of requested size. */
    _tx_byte_allocate(obj, (void**)&pp, bytes);

    /* If no memory, keep existing block and indicate failure to reallocate. */
    if (pp == 0) return pp;

    /* Copy existing block if we were given one. */
    if (ptr)
    {
        /* Make copy of data. */
        memcpy(pp, ptr, bytes);

        /* And we're done with the original block. */
        _tx_byte_release(obj, ptr);
    }

    /* Return newly allocated block. */
    return pp;
}

static void _get_info(void *obj, uint32_t *total, uint32_t *used, uint32_t *max_used)
{
    TX_BYTE_POOL_OBJ *tx_obj = obj;

    *total = tx_obj->tx_byte_pool_size;
    *used = tx_obj->tx_byte_pool_size - tx_obj->tx_byte_pool_available;
    *max_used = *used;

}

/* export */

const _mem_sal_opt mem_tx_sal_opt = 
{
    .name = "ThreadX",
    .func_init = _init,
    .func_free = _free,
    .func_malloc = _malloc,
    .func_realloc = _realloc,
    .func_get_info = _get_info,
};

#endif // CONFIG_MEM_TYPE_THREADX



